package com.mp3player.mp3player;


import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.Toast;

import com.mp3player.download.HttpDownloader;
import com.mp3player.model.Mp3Info;
import com.mp3player.service.DownloadService;
import com.mp3player.util.FileUtils;
import com.mp3player.util.MetaData;
import com.mp3player.util.ToolUtils;

import java.io.File;
import java.util.List;


/**
 * A simple {@link Fragment} subclass.
 */
public class RemoteMp3ListFragment extends Fragment {

    private static final Integer UPDATE = 1;
    private static final Integer ABOUT = 2;
    private static final Integer CLEAR = 3;

    private View rootView = null;

    private HandlerThread handlerThread = null;
    private Handler mp3ListHandler = null;
    private Handler XMLDownloadHandler = null;

    private ListView remoteMp3List = null;

    List<Mp3Info> mp3InfoList = null;

    public RemoteMp3ListFragment() {
        // Required empty public constructor
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        this.setHasOptionsMenu(true);
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        rootView = inflater.inflate(R.layout.fragment_remote_mp3_list, container, false);
        //获得ListView
        remoteMp3List = (ListView) rootView.findViewById(R.id.remote_mp3_list);
//        System.out.println("list view is null --> "+(null == remoteMp3List));

        //新建mp3 ListView 主线程相关的Handler用于处理异步的消息
        mp3ListHandler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                //将MP3信息列表渲染到ListView上
                ToolUtils.renderMp3ListView(mp3InfoList, getContext(), remoteMp3List);
            }
        };

        //新建下载xml的线程，并将Handler绑定到新的线程的Looper上
        handlerThread = new HandlerThread("XMLDownloadHandlerThread");
        handlerThread.start();
        XMLDownloadHandler = new Handler(handlerThread.getLooper());

        //获取ListView，并绑定每一行点击监听
        remoteMp3List = (ListView) rootView.findViewById(R.id.remote_mp3_list);
        remoteMp3List.setOnItemClickListener(new RemoteMp3ListItemSelectListener());

        //翻到远程列表这一页的时候先访问远程服务器获取新的列表
        updateMp3List();

        return rootView;
    }

    class RemoteMp3ListItemSelectListener implements AdapterView.OnItemClickListener {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            Mp3Info mp3Info = mp3InfoList.get(position);
            Intent intent = new Intent();
            intent.putExtra(MetaData.MP3_INFO_KEY, mp3Info);
            intent.setClass(rootView.getContext(), DownloadService.class);
            rootView.getContext().startService(intent);
        }
    }

    class XMLDownloadThread implements Runnable {
        @Override
        public void run() {
//            System.out.println("start downloading xml file");
            String xml = downloadXML(MetaData.getXmlUrl());
//            System.out.println("xml --> "+xml);
            //获得解析出来的MP3信息列表
            mp3InfoList = ToolUtils.parse(xml);
            //向UI的Handler发送更新ListView的消息
            Message message = mp3ListHandler.obtainMessage();
            message.sendToTarget();
        }
    }

    /**
     * 使用一段url下载xml文件并以字符串形式返回xml文件
     * <br/>注意！不要直接在MainActivity的主线程中使用此方法，新版本安卓（4.4）及以上更新的策略会
     * 在主线程访问网络时抛出异常
     * @param urlStr xml的文件url地址
     * @return 字符串形式的xml文件内容
     */
    private String downloadXML(String urlStr) {
        return new HttpDownloader().downloadTextFile(urlStr);
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        menu.add(0, UPDATE, UPDATE, this.getString(R.string.mp3list_update));
        menu.add(0, ABOUT, ABOUT, this.getString(R.string.mp3player_about));
        menu.add(0, CLEAR, CLEAR, this.getString(R.string.mp3player_clear));
        super.onCreateOptionsMenu(menu, inflater);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (UPDATE == item.getItemId()) {
            updateMp3List();
        } else if (ABOUT == item.getItemId()) {
            reportInternalStorage();
        } else if (CLEAR == item.getItemId()) {
            clearInternalStorage();
        }
        return super.onOptionsItemSelected(item);
    }

    /**
     * 更新mp3列表
     */
    private void updateMp3List() {
        try {
            XMLDownloadHandler.post(new XMLDownloadThread());
        } catch (Exception e) {
            e.printStackTrace();
            Toast.makeText(rootView.getContext(), rootView.getContext().getText(R.string.unable_to_access_internet), Toast.LENGTH_SHORT).show();
        }
    }

    /**
     * 报告内置存储空间的情况（测试用）
     */
    private void reportInternalStorage() {
        File[] files = new File(MetaData.root.getAbsolutePath()+FileUtils.SEPERATOR+MetaData.SAVE_DIR).listFiles();
        for (File f : files) {
            System.out.println("detected: "+f.getName()+" is file: "+f.isFile());
        }
    }

    /**
     * 清除内置存储空间（测试用）
     */
    private void clearInternalStorage() {
        File[] files = new File(MetaData.root.getAbsolutePath()+FileUtils.SEPERATOR+MetaData.SAVE_DIR).listFiles();
        for (File f : files) {
            try {
                System.out.print("detected: "+f.getName()+"; is file: "+f.isFile());
                FileUtils.recursiveRemove(f);
                System.out.println("; removed: "+ (!f.exists()));
            } catch (Exception e) {
                e.printStackTrace();
            };
        }
    }

}
